﻿using Flurl.Http;
using Pay.Core;
using Pay.DTO;
using Pay.DTO.mpay;
using Pay.IService;
using Pay.TO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Pay.Service {
    public class MPayService : ServiceBase2, IPayService, IDisposable {
        private IUnitOfWork _iUnitOfWork;
        private ISettingService _iSettingService;
        private IMerchantService _iMerchantService;
        private IChargeService _iChargeService;
        private IRefundService _iRefundService;
        private ITransferService _iTransferService;
        private IProfitDayService _iProfitDayService;
        private IBillService _iBillService;
        private IPayHtmlService _iPayHtmlService;
        private MpaySign _mpaySign;
        public MPayService(IUnitOfWork iUnitOfWork, ISettingService iSettingService,
                                   IMerchantService iMerchantService, IChargeService iChargeService, IRefundService iRefundService,
                                ITransferService iTransferService, IProfitDayService iProfitDayService, IBillService iBillService,
                                  IPayHtmlService iPayHtmlService) : base(iUnitOfWork) {
            _iUnitOfWork = iUnitOfWork;
            _iSettingService = iSettingService;
            _iMerchantService = iMerchantService;
            _iChargeService = iChargeService;
            _iRefundService = iRefundService;
            _iTransferService = iTransferService;
            _iProfitDayService = iProfitDayService;
            _iBillService = iBillService;
            _iPayHtmlService = iPayHtmlService;
            _mpaySign = new MpaySign();
        }
        public async Task<native_result> NativePay(native_model model) {
            var setting = _iSettingService.Get();
            var id = Guid.NewGuid().ToString("N");
            //把商户请求转为通道请求消息
            mpay_model pay_model = new mpay_model ();
            pay_model. amount = model.tran_amount;
            pay_model.notifyUrl = setting.site.api_url + "/mpay_native_notify"  +id;
            pay_model.merchantId = model.merchant_no;
            pay_model.time = DateTime.Now.ToUnix().ToString();
            if (model.pay_code == "WXPAY_QR") pay_model.paymentType = "weChat";
            if(model.pay_code== "ALIPAY_QR") pay_model.paymentType = "alipay";
            pay_model.signType = "MD5";
#if DEBUG
            pay_model.termNo = "00000001";
#else
            pay_model.termNo = "39.108.95.110";//取主机地址
#endif
            pay_model.sign = _mpaySign.Sign(pay_model);
            //调用通道执行并处理返回，请通道响应消息封装为平台响应商户消息
            var pay_rep = _mpaySign.PayGateway(pay_model);
            if (pay_rep .ret=="1") {
                //创建订单
                model.transaction_no = "";
               var charge= _iChargeService.AddByNativePay(model);
                var ok = _iPayHtmlService.Save(new pay_html_dto {
                    id = id, merchant_no = model.merchant_no, order_no = model.order_no,
                    charge = charge.ToJson(), html = "", create_time = DateTime.Now
                });
                var data = new native_result {
                     order_no = model.order_no, code_url = pay_rep.msg, result_msg= "生成成功", transaction_no= pay_rep.orderId
                };
                return await ApiResultToJson.JsonAsync("生成成功", data);
            }
            return await ApiResultToJson.JsonAsync<native_result>("支付失败");
        }
        /// <summary>
        /// 
        /// </summary>
    	/// 回调支付通知，商户返回OK，不再回调了，流程是先调用ChargeService的NotifyOrder，
		/// 返回值判断是调用哪个通道，再调用本方法，最后调用ChargeService的Update
        /// <returns></returns>
        public async Task<string> Notify(string merchant_no, string order_no) {
            string result = string.Empty;
            charge_dto order = _iChargeService.Get(merchant_no, order_no);
            try {
                var data = new pay_notity {
                    tran_amount = ((int)(order.order_amount * 100)).ToString(), order_no = order.order_no, transaction_no = order.pay_info.transaction_no,
                    pay_time = order.pay_info.pay_time.HasValue ? order.pay_info.pay_time.Value : order.order_time,
                    status = (order.status == ChargeStatus.Finish ? 1 : 2)
                };
                
                data.result_msg = (data.status == 1 ? "支付成功" : order.fail);
                if (string.IsNullOrEmpty(order.notify)) return "OK";
                var notify_result = await order.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
                result = notify_result.data;
                var log = IocHelper.Get<ILogHelper>("info");
                log.Info(order.order_no + ":" + notify_result.ToJson());
            } catch (Exception ex) {
                var log = IocHelper.Get<ILogHelper>("info");
                log.Error("订单通道查询异常:" + order.order_no);
                string message = string.Format("消息类型：{0}\r\n消息内容：{1}\r\n引发异常的方法：{2}\r\n引发异常源：{3}"
                                , ex.GetType().Name, ex.Message, ex.TargetSite, ex.Source + ex.StackTrace);
                log.Error(message);
            }
            return result;
        }
        public Task<transfer_result> AgencyFund(apply_receive model) {
            throw new NotImplementedException();
        }

        public Task<certify_verify_result> CertifyVerify(certify_verify model) {
            throw new NotImplementedException();
        }

        public int DealItp(long id) {
            throw new NotImplementedException();
        }

        public Task<gateway_pay_result> GatewayPay(gateway_pay_model model) {
            throw new NotImplementedException();
        }

        public List<type_setting> GatewayPayBank() {
            throw new NotImplementedException();
        }

        public Task<pay_notity> GatewayPayQuery(refund_model_query model) {
            throw new NotImplementedException();
        }

        public Task<refund_result> GatewayPayRefund(refund_model model) {
            throw new NotImplementedException();
        }

        public Task<refund_result> GatewayRefundQuery(refund_model_query model) {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> InsteadReceive(verify_model model) {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> InsteadReceive(verify_model_sms model) {
            throw new NotImplementedException();
        }

        public Task<int> ItpToFile(DateTime create_date) {
            throw new NotImplementedException();
        }

        public Task<mall_result> MallPay(mall_model obj) {
            throw new NotImplementedException();
        }

        public Task<merchant_register_result> MerchantModify(long bind_id, string settle_type, PayChannel channel = PayChannel.None) {
            throw new NotImplementedException();
        }

        public Task<merchant_register_result> MerchantRegister(merchant_register_model dto, string opt) {
            throw new NotImplementedException();
        }

        public Task<merchant_register_result> MerchantRegister(long bind_id, string settle_type, PayChannel channel = PayChannel.None) {
            throw new NotImplementedException();
        }

      

        public Task<string> NotifyTransfer(string merchant_no, string order_no) {
            throw new NotImplementedException();
        }

        public Task<quick_pay_result> QuickPay(quick_pay_model model) {
            throw new NotImplementedException();
        }

        public Task<quick_pay_result> QuickPay(quick_sms_model model) {
            throw new NotImplementedException();
        }

        public Task<pay_notity> QuickPayQuery(refund_model_query model) {
            throw new NotImplementedException();
        }

        public Task<refund_result> QuickPayRefund(refund_model model) {
            throw new NotImplementedException();
        }

        public Task<refund_result> QuickPayRefundQuery(refund_model_query model) {
            throw new NotImplementedException();
        }

        public Task<ApiResultMessage> QuickPaySendsms(quick_sendsms_model model) {
            throw new NotImplementedException();
        }

        public Task<quota_result> Quota(string merchant_no, string busiType) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> ReTransfer(long id) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> Transfer(apply_transfer model) {
            throw new NotImplementedException();
        }

        public Task<batch_transfer_result> Transfer(batch_transfer model) {
            throw new NotImplementedException();
        }

        public Task<int> TransferBack(long batchId, string noticeTranId, long merchant_id) {
            throw new NotImplementedException();
        }

        public Task<int> TransferNotify(long batchId, string batchFileName, long merchant_id) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TransferQuery(transfer_query model) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransfer(long id) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransferQuery(transfer_query model) {
            throw new NotImplementedException();
        }
    }
}
